home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright 1991, 1992, 1993, 1994, Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
- * the contents of this file may not be disclosed to third parties, copied or
- * duplicated in any form, in whole or in part, without the prior written
- * permission of Silicon Graphics, Inc.
- *
- * RESTRICTED RIGHTS LEGEND:
- * Use, duplication or disclosure by the Government is subject to restrictions
- * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
- * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
- * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
- * rights reserved under the Copyright Laws of the United States.
- */
- /*
- * curve.c
- *
- * This is the main file for the Curve Demo.
- *
- * This program gives a demonstration of the use of the GL
- * graphics library to create different types of curves in both
- * two and three dimensions. The user may select among different
- * types of splines to approximate the curve, view the the control
- * points that define the curve, manipulate the control points to see
- * the effect on the resulting curve, as well as a host of other
- * "whiz-bangs" including setting the curve in motion, viewing the
- * curve in 3D perspective, and more.
- *
- * OPERATION
- * Type
- * curve <ENTER>
- * to begin the demo. To quit, select quit from the menu, or press the
- * ESC key.
- *
- * LEFT MOUSE
- * adds a control point in both 2D and 3D modes. Control points are
- * given a random z value, which is apparent in 3D mode. If the left
- * mouse button is held while adding a point, that point may be moved
- * around. Otherwise, control points may be moved after they are added
- * using the...
- *
- * MIDDLE MOUSE
- * In 2D mode, the middle allows a control point to be moved by
- * pointing at it, pressing and holding the middle button, then
- * dragging the control point to a new location.
- * In 3D mode, the middle mouse allows manipulation of the view
- * volume. When the middle mouse is pressed and dragged within the
- * volume, the volume is rotated trackball style around the world x
- * and y axes. When the middle mouse is pressed and dragged outside
- * the view volume, the volume is rotated about the z axis.
- *
- * RIGHT MOUSE
- * brings up the menus. Menus are fairly self explanatory. The Options
- * menu allows the user to add all kinds of whizzy things to the
- * display. For some real fun, put the program in 3D mode, then turn
- * markers off, smear on, then motion on. Toss in a handful of control
- * points (with the left mouse button), then sit back and enjoy.
- * The truly daring may manipulate the view volume (with the middle
- * mouse) while all this is hapening.
- *
- * BACKSPACE Key
- * deletes the control point nearest to the cursor in both 2D and 3D
- * modes.
- *
- * Written by Howard Look for Silicon Graphics, Inc.
- * Based upon the initial program written by Rocky Rhodes and Herb Kuta
- * Plenty of help from Thant Tessman^, Gavin Bell and Keith Seto
- *
- * ^Twinkies for convex hulls and tons of help
- *
- * June, 1989
- *
- */
-
-
- #include <stdio.h>
- #include <gl.h>
- #include <device.h>
- #include <math.h>
- #include <fmclient.h>
- #include "event.h"
- #include "curve.h"
- #include "spaced.h"
-
-
-
- /* Prototypes */
- void init_window(char *argv[]);
- void init_events(void);
- void redraw(void);
- void process_left_down(void);
- void process_left_up(void);
- void process_middle_down(void);
- void process_middle_up(void);
- void process_mouse_motion(void);
- void draw_instructions(Boolean);
- void quit(void);
- void init_fonts(void);
- void help(void);
- void end_help(void);
- Boolean helping(void);
-
- extern void init_menus(void);
- extern void init_basis(void);
- extern void init_linestyles(void);
- extern void add_control_point(void);
- extern void delete_control_point(int);
- extern void move_control_point(int);
- extern void draw_display(void);
- extern void clear_window(void);
- extern Boolean hit_control_point(int *);
-
- /* Environment variables */
- int curve_basis,
- display_mode,
- curve_precision,
- speed,
- line_style,
- whizbang;
- Boolean markers,
- hulls,
- motion,
- smear,
- rotating;
-
- extern Boolean moving;
-
- /* type of hardware we are running on */
- int hardware;
-
-
- /* Is drawing active ? */
- Boolean draw_active;
-
-
- /* Lower left corner of the window */
- int origin_x, origin_y;
-
-
- /* Size of the window */
- int size_x, size_y;
-
- /* Window's aspect ratio, x/y */
- float aspect;
-
- extern Coord geometry[MAX_MARKERS][3];
- extern int nailed_marker;
- extern Matrix everything_matrix;
-
- void main(int argc, char *argv[])
- {
-
- /* Don't hog the graphics unless necessary */
- draw_active = FALSE;
-
- /* initialize everything */
- init_window(argv);
-
- init_fonts();
- draw_instructions(TRUE);
-
- init_basis();
- init_linestyles();
- init_menus();
- init_events();
-
- help();
-
- /* event() looks for the events (as in init_events) and passes
- them on to the appropriate routines */
- while(TRUE)
- event();
- }
-
-
- /*
- * Opens the window and sets up the graphic mode.
- */
- void init_window(char *argv[])
- {
- char *t, *strrchr();
-
- if (getgdesc(GD_BITS_NORM_ZBUFFER) == 0)
- {
- system("inform 'Your system must have a z-buffer to run curve'");
- exit(1);
- }
-
- keepaspect(1,1);
- /* open the window with its invocation as the title (less the path) */
- winopen((t=strrchr(argv[0], '/')) != NULL ? t+1 : argv[0]);
-
- /*
- * Assume that if we have fewer than 4 RGB bitplanes, may as
- * well run in colorindex mode.
- */
- if (getgdesc(GD_BITS_NORM_DBL_RED) < 4)
- hardware = ECLIPSE8;
- else if (getgdesc(GD_BITS_NORM_DBL_RED) >= 8)
- hardware = ECLIPSE24;
- else
- hardware = GT;
-
- doublebuffer();
-
- if (hardware != ECLIPSE8)
- RGBmode();
-
- zbuffer(TRUE);
- gconfig();
-
- glcompat(GLC_ZRANGEMAP, 0);
-
- getorigin(&origin_x, &origin_y);
- getsize(&size_x, &size_y);
-
- aspect = (float)size_x/(float)size_y;
- }
-
-
- /*
- * Tells event manager what to pay attention to.
- */
- void init_events(void)
- {
- /* ESC key and WINQUIT quit the program */
- add_event(ANY, ESCKEY, UP, quit, 0);
- qdevice(ESCKEY);
- add_event(ANY, WINQUIT, ANY, quit, 0);
- qdevice(WINQUIT);
-
- /* window redraw events */
- add_event(ANY, REDRAW, ANY, redraw, 0);
- qdevice(REDRAW);
-
- add_event(ANY, LEFTMOUSE, DOWN, process_left_down, NULL);
- add_event(ANY, LEFTMOUSE, UP, process_left_up, NULL);
- qdevice(LEFTMOUSE);
-
- add_event(ANY, MIDDLEMOUSE, DOWN, process_middle_down, NULL);
- add_event(ANY, MIDDLEMOUSE, UP, process_middle_up, NULL);
- qdevice(MIDDLEMOUSE);
-
- add_event(ANY, MOUSEX, ANY, process_mouse_motion, NULL);
- add_event(ANY, MOUSEY, ANY, process_mouse_motion, NULL);
-
- /* Backspace deletes the nearest control marker */
- add_event(ANY, BACKSPACEKEY, DOWN, delete_control_point, NULL);
- qdevice(BACKSPACEKEY);
-
- /* Draw the curve whenever the user does not request anything */
- /* i.e., there are no events happening */
- add_update(&draw_active, draw_display, NULL);
- }
-
-
- /*
- * Called by the event manager whenever a redraw event occurs,
- * e.g. when the window is resized.
- */
- void redraw(void)
- {
- getorigin(&origin_x, &origin_y);
- getsize(&size_x, &size_y);
- aspect = (float)size_x/(float)size_y;
- viewport(0, size_x-1, 0, size_y-1);
-
- if (helping())
- help();
- else
- draw_display();
- }
-
-
- void process_left_down(void)
- {
- int marker;
-
- end_help();
-
- if (hit_control_point(&marker))
- move_control_point(marker);
- else
- add_control_point();
- }
-
-
- void process_left_up(void)
- {
- unqdevice(MOUSEX);
- unqdevice(MOUSEY);
-
- moving = FALSE;
- end_spaced();
- draw_display();
- }
-
-
- void process_middle_down(void)
- {
- int marker;
-
- end_help();
-
- if (display_mode == TWO_D)
- {
- if (hit_control_point(&marker))
- move_control_point(marker);
- }
- else
- rotate_view_volume();
- }
-
-
- void process_middle_up(void)
- {
- unqdevice(MOUSEX);
- unqdevice(MOUSEY);
-
- rotating = FALSE;
- moving = FALSE;
- }
-
-
-
- /* limits of the view volume */
- Coord box_limit[3][2] =
- { { -1.0, 1.0},
- { -1.0, 1.0},
- { -1.0, 1.0}
- };
-
-
- void process_mouse_motion(void)
- {
-
- if (rotating && getbutton(MIDDLEMOUSE))
- {
- update_rotation();
- draw_display();
- }
- else if (moving && (getbutton(LEFTMOUSE)||getbutton(MIDDLEMOUSE)))
- {
- if (display_mode == TWO_D)
- track_motion();
- else
- spaced(everything_matrix, geometry[nailed_marker], box_limit);
-
- draw_display();
- }
-
- }
-
-
-
-
- /*
- * Outta here.
- */
- void quit(void)
- {
- gexit();
- exit(0);
- }
-
-
-
-
- /*
- * Routines for writing the intro messages to the screen.
- */
-
- double min(double x, double y)
- {
- if (x < y)
- return x;
- else
- return y;
- }
-
- static fmfonthandle base_font, scaled_font;
-
-
-
- void init_fonts(void)
- {
- fminit();
- base_font = fmfindfont("Times-Roman");
- }
-
-
- void setup_string(char str[100], int size, Coord *half)
- {
- double h_size, v_size, f_size;
- Coord length;
-
- h_size = (double)size_x/(double)size;
- v_size = (double)size_y/(double)size;
- f_size = min(h_size, v_size);
- scaled_font = fmscalefont(base_font, f_size);
- fmsetfont(scaled_font);
-
- length = fmgetstrwidth(scaled_font, str);
- *half = (Coord)(length/size_x);
- }
-
- static int looking_at_help;
- static int active_state;
-
- void help(void)
- {
- if (!looking_at_help)
- {
- looking_at_help = TRUE;
-
- active_state = draw_active;
- draw_active = FALSE;
- }
- draw_instructions(FALSE);
- }
-
- void end_help(void)
- {
- if (looking_at_help)
- {
- looking_at_help = FALSE;
- draw_active = active_state;
- }
- }
-
- Boolean helping(void)
- {
- return looking_at_help;
- }
-
- void draw_instructions(Boolean initializing)
- {
- Coord half;
- char str[100];
-
- ortho2(-1.0, 1.0, -1.0, 1.0);
- czclear(0,getgdesc(GD_ZMAX));
- depthcue(FALSE);
-
- sprintf(str,"Curve");
- setup_string(str,20,&half);
- cmov2(0.0 - half, 0.7);
- if (hardware == ECLIPSE8)
- color(GREEN);
- else
- cpack(0xFF00);
- fmprstr(str);
-
- sprintf(str,"Interactive Cubic Curve Demonstration");
- setup_string(str,40,&half);
- cmov2(0.0 - half, 0.6);
- if (hardware == ECLIPSE8)
- color(GREEN);
- else
- cpack(0xFF00);
- fmprstr(str);
-
- sprintf(str,"Press the left mouse button to add a new control point,");
- setup_string(str,50,&half);
- cmov2(0.0 - half, 0.3);
- if (hardware == ECLIPSE8)
- color(WHITE);
- else
- cpack(0xFFFFFF);
- fmprstr(str);
-
- sprintf(str,"or to move an existing control point.");
- setup_string(str,50,&half);
- cmov2(0.0 - half, .24);
- fmprstr(str);
-
- sprintf(str,"In 3D mode, use the middle mouse button");
- setup_string(str,50,&half);
- cmov2(0.0 - half, .14);
- fmprstr(str);
-
- sprintf(str,"to rotate the view volume.");
- setup_string(str,50,&half);
- cmov2(0.0 - half, .08);
- fmprstr(str);
-
- sprintf(str,"Press the right mouse button to bring up a pop-up menu.");
- setup_string(str,50,&half);
- cmov2(0.0 - half, -.02);
- fmprstr(str);
-
- sprintf(str,"Choose \"Display Mode\" to switch from 2D to 3D.");
- setup_string(str,50,&half);
- cmov2(0.0 - half, -.08);
- fmprstr(str);
-
- sprintf(str,"For some interesting shapes, choose a \"Whizbang\" from the");
- setup_string(str,50,&half);
- cmov2(0.0 - half, -.18);
- fmprstr(str);
-
- sprintf(str,"Options menu.");
- setup_string(str,50,&half);
- cmov2(0.0 - half, -.24);
- fmprstr(str);
-
- sprintf(str,"For more information, please see the man page.");
- setup_string(str,50,&half);
- cmov2(0.0 - half, -.34);
- fmprstr(str);
-
- if (initializing)
- {
- sprintf(str,"Initializing. Please Wait...");
- setup_string(str,40,&half);
- cmov2(0.0 - half, -.70);
- if (hardware == ECLIPSE8)
- color(RED);
- else
- cpack(0xFF);
- fmprstr(str);
- }
-
-
- swapbuffers();
- }
-
-